/*
 * This file is part of PDBEdit.
 * 
 * PDBEdit is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * PDBEdit is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with PDBEdit.  If not, see <http://www.gnu.org/licenses/>.
 *  
 * Creation date : 31/08/2010
 * Copyright (c) Guerfyld 2010. All rights reserved.
 * http://......
 */
package pdbfile;

/**
 * The PDBRecord class manage a PilotDB data record
 *
 * @author guerfyld
 * @version 1.0
 */
public class PDBRecord {
	// Constants
	public static final int ATTRIB_DELETED  = 0x80;
	public static final int ATTRIB_DIRTY    = 0x40;
	public static final int ATTRIB_BUSY     = 0x20;
	public static final int ATTRIB_SECRET   = 0x10;
	public static final int ATTRIB_CATEGORY = 0x0F;

	private long offset;
	private int attrib;
	private long uniqID;
	private PDBType[] vals;

	/**
	 * Constructor
	 *
	 * @param nbCols	Number of columns in record
	 */
	public PDBRecord(int nbCols) {
		offset = -1;
		attrib = 0;
		uniqID = 0;
		vals = new PDBType[nbCols];
	}

	/**
	 * Constructor
	 *
	 * @param off		Record offset
	 * @param att		Record attributes
	 * @param id		Record unique ID
	 */
	public PDBRecord(long off, int att, long id) {
		offset = off;
		attrib = att;
		uniqID = id;
		vals = null;
	}

	/**
	 * Set number of columns in record
	 *
	 * @param nbCols	Number of columns in record
	 */
	public void setNbCol(int nbCols) {
		vals = new PDBType[nbCols];
	}

	/**
	 * Set record unique ID
	 *
	 * @param id		Record unique ID
	 */
	public void setUniqueId(long id) {
		uniqID = id;
	}

	/**
	 * Set column value
	 *
	 * @param val		Value
	 * @param pos		Column number
	 */
	public void setValue(PDBType val, int col) throws Exception {
		try {
			vals[col] = val;
		}
		catch (Exception e) {
			throw new Exception("PDBRecord.setValue : "+e.getMessage());
		}
	}

	/**
	 * Set record as deleted
	 */
	public void setDeleted() {
		attrib = attrib | ATTRIB_DELETED;
	}

	/**
	 * Get record offset
	 *
	 * @return		Record offset
	 */
	public long getOffset() {
		return offset;
	}

	/**
	 * Get record attributes
	 *
	 * @return		Record attribute
	 */
	public int getAttrib() {
		return attrib;
	}

	/**
	 * Get record unique ID
	 *
	 * @return		Record unique ID
	 */
	public long getUniqueId() {
		return uniqID;
	}

	/**
	 * Get column value
	 *
	 * @param col		Column number
	 * @return		Value
	 */
	public PDBType getValue(int col) throws Exception {
		try {
			return vals[col];
		}
		catch (Exception e) {
			throw new Exception("PDBRecord.getValue : "+e.getMessage());
		}
	}

	/**
	 * Get all columns value
	 *
	 * @return		Values
	 */
	public PDBType[] getValues() {
		int nbCols = vals.length;
		PDBType[] ret = new PDBType[nbCols];
		for(int c=0; c<nbCols; c++) {
			try {
				ret[c] = getValue(c).clone();
			}
			catch (Exception e) {
				ret[c] = null;
			}
		}

		return ret;
	}

	/**
	 * Test if record is deleted
	 */
	public boolean isDeleted() {
		return ((attrib & ATTRIB_DELETED) != 0);
	}

	/**
	 * Get record length
	 *
	 * @return		Record length
	 */
	public long length() {
		int nbCols = vals.length;
		long length = 2*nbCols; // length of column offset in record
		for (int c=0; c<nbCols; c++) {
			try {
				length += vals[c].length();
			}
			catch (Exception e) {}
		}

		return length;
	}

	/**
	 * Returns a string representation of the object
	 *
	 * @return	A string representation of the object
	 */
	public String toString() {
		int nbCols = vals.length;
		StringBuffer sb = new StringBuffer(50);
		for (int c=0; c<nbCols; c++) {
			if (c != 0) sb.append(" - ");
			try {
				sb.append(vals[c].toString());
			}
			catch (Exception e) {}
		}
		return sb.toString();
	}

	/**
	 * Creates a new object of the same class as this object
	 *
	 * @return	A new object
	 */
	public PDBRecord clone() {
		PDBRecord rec = new PDBRecord(offset, attrib, uniqID);
		int nbCols = vals.length;
		rec.setNbCol(nbCols);
		rec.vals = getValues();

		return rec;
	}
}
